﻿using System;
using System.Windows.Input;

using Outcoder.Concurrency;

using Xamarin.Forms;

namespace Outcoder.UI.Xaml
{
    public class AppBarItem : AppBarItemBase
    {
	    static AppBarItem()
	    {
			CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(AppBarItem), null, BindingMode.OneWay, null, HandleCommandChanged);
			CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(AppBarItem), null, BindingMode.OneWay, null, HandleCommandParameterChanged);
	    }

		static void HandleCommandParameterChanged(BindableObject bindableObject, object oldvalue, object newvalue)
	    {
			var item = (AppBarItem)bindableObject;

			if (item == null)
			{
				return;
			}

			var command = item.Command;
			if (command != null)
			{
				command.CanExecute(newvalue);
			}
	    }

	    static void HandleCommandChanged(BindableObject bindableObject, object oldValue, object newValue)
	    {
		    var item = (AppBarItem)bindableObject;
			
		    if (item == null)
		    {
			    return;
		    }

		    ICommand command = (ICommand)newValue;

			BindToCommand(item, command);
	    }

	    static void BindToCommand(AppBarItem item, ICommand command)
	    {
			if (command != null)
			{
				var newUICommand = command as IUICommand;
				if (newUICommand != null)
				{
					/* Without a relative source binding capability we can't bind to the command. */
					{
						if (string.IsNullOrEmpty(item.Text))
						{
							item.SetBinding(TextProperty, new Binding("Command.Text", BindingMode.OneWay));
						}

						if (!string.IsNullOrEmpty(newUICommand.IconUrl))
						{
							item.SetBinding(IconUriProperty, "Command.IconUrl", BindingMode.OneWay, new StringToUriConverter());
						}

						item.SetBinding(IsEnabledProperty, new Binding("Command.Enabled", BindingMode.OneWay));
					}
				}
			}
	    }

	    public static readonly BindableProperty CommandProperty;

	    public ICommand Command
	    {
		    get
		    {
			    return (ICommand)GetValue(CommandProperty);
		    }
		    set
		    {
			    SetValue(CommandProperty, value);
		    }
	    }

		public static readonly BindableProperty CommandParameterProperty;

		public object CommandParameter
		{
			get
			{
				return GetValue(CommandParameterProperty);
			}
			set
			{
				SetValue(CommandParameterProperty, value);
			}
		}

	    protected override void OnTap(EventArgs e)
	    {
		    base.OnTap(e);

		    var command = Command;
		    if (command != null)
		    {
			    command.Execute(CommandParameter);
		    }
	    }
    }
}
